﻿/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 **/

using System;
using System.Windows.Media;
using System.Windows.Threading;
using Peter.Common;
using Peter.Common.Interfaces;
using Peter.Common.Services;

namespace Peter.Logic
{
   /// <summary>
   /// Represents the status bar model.
   /// </summary>
   public class ModelStatus : ViewModelBase, IStatus
   {
      private int m_CharOffset;
      private int m_LineNumber;
      private int m_ColumnNumber;
      private string m_Status;
      private readonly DispatcherTimer m_Timer;
      private Brush m_Foreground;
      private Brush m_Background;

      /// <summary>
      /// Initializes a new status model object.
      /// </summary>
      public ModelStatus ()
      {
         this.Status = "Welcome";
         this.m_Timer = new DispatcherTimer (DispatcherPriority.Normal, Dispatcher.CurrentDispatcher);
         this.m_Timer.Tick += this.OnTimerTick;
         ServiceManager.AddSingleton<IStatus, ModelStatus> (this);
      }

      /// <summary>
      /// Gets or Sets the status.
      /// </summary>
      public string Status
      {
         get { return this.m_Status; }
         set
         {
            this.m_Status = value;
            this.OnPropertyChanged ("Status");
         }
      }

      /// <summary>
      /// Gets or Sets the current character offset.
      /// </summary>
      public int CharacterOffset
      {
         get { return this.m_CharOffset; }
         set
         {
            this.m_CharOffset = value;
            this.OnPropertyChanged ("CharacterOffset");
         }
      }

      /// <summary>
      /// Gets or Sets the current column number.
      /// </summary>
      public int ColumnNumber
      {
         get { return this.m_ColumnNumber; }
         set
         {
            this.m_ColumnNumber = value;
            this.OnPropertyChanged ("ColumnNumber");
         }
      }

      /// <summary>
      /// Gets or Sets the current line number.
      /// </summary>
      public int LineNumber
      {
         get { return this.m_LineNumber; }
         set
         {
            this.m_LineNumber = value;
            this.OnPropertyChanged ("LineNumber");
         }
      }

      /// <summary>
      /// Gets or Sets the forground of the status message.
      /// </summary>
      public Brush Foreground
      {
         get { return this.m_Foreground; }
         set
         {
            this.m_Foreground = value;
            this.OnPropertyChanged ("Foreground");
         }
      }

      /// <summary>
      /// Gets or Sets the background of the status message.
      /// </summary>
      public Brush Background
      {
         get { return this.m_Background; }
         set
         {
            this.m_Background = value;
            this.OnPropertyChanged ("Background");
         }
      }

      /// <summary>
      /// Sets the status in the status bar.
      /// </summary>
      /// <param name="message">Message to display</param>
      /// <param name="delay">Amount of time to show message - default is 5 seconds.</param>
      /// <param name="type">The type of status to display - default is normal.</param>
      public void SetStatus (string message, StatusTimeDelay delay = StatusTimeDelay.Medium, StatusType type = StatusType.Normal)
      {
         this.Status = message;
         this.m_Timer.Interval = new TimeSpan (0, 0, 0, (int) delay);

         this.SetColors (type);
         if (delay != StatusTimeDelay.Indefinite)
         {
            if (this.m_Timer.IsEnabled)
               this.m_Timer.Stop ();
            this.m_Timer.Start ();
         }

         if (type == StatusType.Error)
            Console.Error.WriteLine (message);
         else
            Console.WriteLine (message);
      }

      /// <summary>
      /// Sets the colors of the status bar.
      /// </summary>
      /// <param name="type"></param>
      private void SetColors (StatusType type)
      {
         if (type == StatusType.Warning)
         {
            this.Foreground = Brushes.Black;
            this.Background = Brushes.Yellow;
         }
         else if (type == StatusType.Error)
         {
            this.Foreground = Brushes.White;
            this.Background = Brushes.Red;
         }
         else if (type == StatusType.Highlight)
         {
            this.Foreground = Brushes.Black;
            this.Background = Brushes.CornflowerBlue;
         }
         else
         {
            this.Foreground = Brushes.Black;
            this.Background = Brushes.Transparent;
         }
      }

      /// <summary>
      /// Occurs when the status timer ticks.
      /// </summary>
      /// <param name="sender">Status timer.</param>
      /// <param name="e">EventArgs</param>
      private void OnTimerTick (object sender, EventArgs e)
      {
         this.m_Timer.Stop ();
         this.Status = string.Empty;
         this.SetColors (StatusType.Normal);
      }
   }
}
